%{
	#include "jack-gram.h"
	#include <string.h>
	#include <stdlib.h>
	#include <stdio.h>
	extern FILE *yyin;
	extern int nrolinea;
	#define MIN -32768
	#define MAX 32767
	void printToken(int, char*, int);
	void contarSaltoLinea(char*);	
	int errorLexico(char *);
	int perteneceRango(int);
	
%}
letra	[a-zA-Z]
digito	[0-9]
%%

"("			{ /* printToken(TPARA, yytext, nrolinea); */   return TPARA;  }
")"			{ /* printToken(TPARC, yytext, nrolinea); */   return TPARC;  }
"["         { /* printToken(TCRA, yytext, nrolinea); */    return TCRA;   }
"]"         { /* printToken(TCRC, yytext, nrolinea); */    return TCRC;   }
"{"			{ /* printToken(TLLA, yytext, nrolinea); */    return TLLA;	}
"}"			{ /* printToken(TLLC, yytext, nrolinea); */    return TLLC;	}
","			{ /* printToken(TCOMA, yytext, nrolinea); */   return TCOMA;  }
";"			{ /* printToken(TPCOMA, yytext, nrolinea); */  return TPCOMA; }
"="			{ /* printToken(TIGUAL, yytext, nrolinea); */  return TIGUAL; }
"."			{ /* printToken(TPUNTO, yytext, nrolinea); */  return TPUNTO; }
"+"			{ /* printToken(TMAS, yytext, nrolinea); */    return TMAS;   }
"-"			{ /* printToken(TMENOS, yytext, nrolinea); */  return TMENOS; }
"*"			{ /* printToken(TMULT, yytext, nrolinea); */   return TMULT;  }
"/"			{ /* printToken(TDIV, yytext, nrolinea); */    return TDIV;   }
"&"			{ /* printToken(TAND, yytext, nrolinea); */    return TAND;   }
"|"			{ /* printToken(TOR, yytext, nrolinea); */     return TOR;    }
"~"			{ /* printToken(TNOT, yytext, nrolinea); */    return TNOT;   }
">"			{ /* printToken(TMAY, yytext, nrolinea); */    return TMAY;   }
"<"			{ /* printToken(TMEN, yytext, nrolinea); */    return TMEN;   }
class		{ /* printToken(TCLASS, yytext, nrolinea); */  return TCLASS; }
constructor { /* printToken(TCONST, yytext, nrolinea); */  return TCONST; }
method		{ /* printToken(TMETHOD, yytext, nrolinea); */ return TMETHOD;}
function	{ /* printToken(TFUNCT, yytext, nrolinea); */  return TFUNCT; }
int			{ /* printToken(TINT, yytext, nrolinea); */    return TINT;   }
boolean		{ /* printToken(TBOOL, yytext, nrolinea); */   return TBOOL;  }
char		{ /* printToken(TCHAR, yytext, nrolinea); */   return TCHAR;  }
void		{ /* printToken(TVOID, yytext, nrolinea); */   return TVOID;  }
var			{ /* printToken(TVAR, yytext, nrolinea); */    return TVAR;   }
static		{ /* printToken(TSTAT, yytext, nrolinea); */   return TSTAT;  }
field		{ /* printToken(TFLD, yytext, nrolinea); */    return TFLD;   }
let			{ /* printToken(TLET, yytext, nrolinea); */    return TLET;   }
do			{ /* printToken(TDO, yytext, nrolinea); */     return TDO;    }
if			{ /* printToken(TIF, yytext, nrolinea); */     return TIF;    }
else		{ /* printToken(TELSE, yytext, nrolinea); */   return TELSE;  }
while		{ /* printToken(TWHILE, yytext, nrolinea); */  return TWHILE; }
return		{ /* printToken(TRETURN, yytext, nrolinea); */ return TRETURN;}
true		{ /* printToken(TTRUE, yytext, nrolinea); */   return TTRUE;  }
false		{ /* printToken(TFALSE, yytext, nrolinea); */  return TFALSE; }
null		{ /* printToken(TNULL, yytext, nrolinea); */   return TNULL;  }
this		{ /* printToken(TTHIS, yytext, nrolinea); */   return TTHIS;  }




"\""(.)*"\"" {  yylval.lexema = (char *)strdup(yytext);  /* printToken(TCTECHAR, yytext, nrolinea); */  return TCTECHAR; }

"-"?{digito}+ { if (perteneceRango(atoi(yytext))){
					yylval.lexema = (char *)strdup(yytext);
					/* printToken(TCTEINT, yytext, nrolinea); */ return TCTEINT;
			  }
			  else
				  errorLexico("Entero fuera del rango");
}				


({letra}|"_")+({letra}|{digito}|"_")* { yylval.lexema = (char *)strdup(yytext); /* printToken(TID, yytext, nrolinea); */ return TID; }

("/")("*")+([^"*/"]|\n)*"*/" { contarSaltoLinea(yytext); }
"//"(.)*         

[ \t]+ 		/* obvia espacios en blanco, tabuladores */
\n      	{ nrolinea++; }
.			{ printf("Error Lexico: simbolo %s no valido en la linea %d\n", yytext, nrolinea ); }

%%

void printToken(int token, char* lex, int linea){
	printf("token ID: %d , lexema: \"%s\" , #linea: %d\n", token, lex, linea); 
}

/* Cuenta los saltos de linea */
void contarSaltoLinea(char* linea){
	int i;	
	for(i = 0; i < strlen(linea); i++)
		if(linea[i] == '\n')
		{ nrolinea++; }		
}

/* Imprime los errores */
int errorLexico(char *s){
	printf("Error Lexico en la linea %d:",nrolinea);
	printf(" %s\n",s);
	return 0;
}


int perteneceRango(int num)
{
	return ((num >= MIN) && (num <= MAX));
}
